This Rmarkdown contain code to obtain all plot necessary to produce our bioinformatical related figures. Final figure anotation and layout were then produce with inkscape.

FIGURE 2

Panel A

# Highlight specific HTO  6x4
Idents(T.Seurat) <- "MULTI_ID"
cellM <- WhichCells(T.Seurat, idents = c("Spleen-M","Thymus-M") )
plotM <- DimPlot(T.Seurat,cells.highlight = cellM,sizes.highlight = 0.5,cols = "grey80", cols.highlight = "coral2",pt.size = 0.5)+ NoLegend()+NoAxes()

cellctrl <- WhichCells(T.Seurat, idents = c("Spleen-ctrl","Thymus-ctrl") )
plotC <- DimPlot(T.Seurat,cells.highlight = cellctrl,sizes.highlight = 0.5,cols = "grey80", cols.highlight="chartreuse4",pt.size = 0.5)+ NoLegend()+NoAxes()

cellMP <- WhichCells(T.Seurat, idents = c("Spleen-MP","Thymus-MP") )
plotMP <- DimPlot(T.Seurat,cells.highlight = cellMP,sizes.highlight = 0.5,cols = "grey80", cols.highlight="#CC0099",pt.size = 0.5)+ NoLegend()+NoAxes()

cellP <- WhichCells(T.Seurat, idents = c("Spleen-P","Thymus-P") )
plotP <- DimPlot(T.Seurat,cells.highlight = cellP,sizes.highlight = 0.5,cols = "grey80", cols.highlight="deepskyblue3",pt.size = 0.5)+ NoLegend()+NoAxes()

#thymus vs rate figure
plotorgan <- DimPlot(T.Seurat, group.by = "tissue",cols=c("darkgoldenrod1","darkred"),pt.size = 0.5)+ NoLegend()+NoAxes()
panA <- grid.arrange(plotM, plotP,plotMP,plotC,plotorgan, nrow = 3)

Panel B

Idents(T.Seurat) <- "integrated_snn_res.1.8"
umapcols <- c("#99A6E7","#E3B1D6","#F78754","#F94A17","#CC79B7","#6477D8","#919296","#CF063A","#FEA981","#55AC7C","#5F4090","#D13A7C","#1332D0","#EC0067","#FB710D","#09B329","#B23ACE","#7A1E45","#FB920D","#FF35AC","#FBAF0D","#ECB90C","#FFDA0D","#E22611")


DimPlot(T.Seurat, reduction = "umap", group.by = "integrated_snn_res.1.8", pt.size = 1,cols = umapcols)+ NoLegend()

panB <- DimPlot(T.Seurat, reduction = "umap", group.by = "integrated_snn_res.1.8", pt.size = 1,cols = umapcols)+ NoLegend()

Panel C

#Dotplot thymus
Idents(T.Seurat.thymus) <- "manualclusters"
T.Seurat.thymus@active.ident <- factor(T.Seurat.thymus@active.ident,levels=c("22","21","20,18,14","8,2,3,23","7","6","10,16","17"))
levels(T.Seurat.thymus)
## [1] "22"       "21"       "20,18,14" "8,2,3,23" "7"        "6"       
## [7] "10,16"    "17"
dotplotthym <- DotPlot(T.Seurat.thymus, dot.scale = 14,features = c("percent.mito","Bmf","Trp53inp1","Tox2","Cd5","Cd69","Cd27","Rag1","Rag2","Cd4","Cd8a","Cd8b1","Mki67","Cdk1","Ptcra","Il2ra","Cd34")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + coord_flip()+ theme(
   legend.text = element_text(size = 20),
  legend.title = element_text(size = 25),
  axis.text.x = element_text(size = 20,angle = 90),
  axis.text.y = element_text(size = 20),
  axis.title = element_text(size = 25),
  panel.background = element_rect(fill = "grey65",
                                size = 0.5, linetype = "solid"),
  panel.grid.major = element_line(size = 0.5, linetype = 'solid',
                                colour = "grey55"))
#dot scale was 8 but change for rmarkdown output
# Dotplot spleen
Idents(T.Seurat.spleen) <- "manualclusters"

T.Seurat.spleen@active.ident <- factor(T.Seurat.spleen@active.ident,levels=c("10,16","1","4","0,5","12","15","9","17","13","11","19"))
dotplotspleen <- DotPlot(T.Seurat.spleen, dot.scale = 14, features= c("Foxp3","Aes","Anxa1","Gzma","Ccl5","Cxcr3","Sell","S1pr1","Ccr7","Trdc","Tcrg-C4","Tcrg-C2","Tcrg-C1","Trbc2","Trbc1","Trac","Cd8b1","Cd4")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + theme(
  legend.text = element_text(size = 20),
  legend.title = element_text(size = 25),
  axis.text.x = element_text(size = 20,angle = 90),
  axis.text.y = element_text(size = 20),
  axis.title = element_text(size = 25),
  panel.background = element_rect(fill = "grey65",
                                size = 0.5, linetype = "solid"),
  panel.grid.major = element_line(size = 0.5, linetype = 'solid',
                                colour = "grey55")) + coord_flip()
#dot scale was 8 but change for rmarkdown output
#Combine dotplot
panC <- grid.arrange(dotplotthym,dotplotspleen, ncol = 2)

Panel D

#check par
par(oma = c(0, 0, 0, 0))
par(mar = c(0,1,0,1))
par(mfrow=c(1,2))
#check genotype proportion in each spleen clusters

df <- as.data.frame(as.data.frame.matrix(t(prop.table(table(T.Seurat.spleen@meta.data$HTO,T.Seurat.spleen@meta.data$manualclusters),1)*100)))
df$cluster = rownames(df)
df2<-as.data.frame(t(cbind(rep(60,11),rep(0,11),df)[,1:6]))
rownames(df2[1:2,]) <- c("60","0")

#order data frame
df2 <- df2[c("10,16","19","11","13","17","9","15","12","0,5","4","1")]

radarspleen <- radarchart(df2, cglcol="grey", cglty=1 ,cglwd=0.8, vlcex=0.8, pcol=c("#FF99FF","coral1","cyan3","chartreuse3") , plwd=3, plty=1 ,caxislabels=paste(seq(from = 0,to = 60,by = 15),"%"), axislabcol = "grey40", axistype = 0)

#check genotype proportion in each thymic cluster
df <-  as.data.frame(as.data.frame.matrix(t(prop.table(table(T.Seurat.thymus@meta.data$HTO,T.Seurat.thymus@meta.data$manualclusters),1)*100)))
df$cluster = rownames(df)
df2<-as.data.frame(t(cbind(rep(65,8),rep(0,8),df)[,1:6]))
rownames(df2[1:2,]) <- c("65","0")

#order
df2 <- df2[c("22","17","10,16","6","7","8,2,3,23","20,18,14","21")]


radarthymus <- radarchart(df2, cglcol="grey", cglty=1,caxislabels=paste(seq(0,70,17.5),"%"), axistype = 0,axislabcol="grey40", cglwd=0.8, vlcex=0.8, pcol=c("#FF99FF","coral1","cyan3","chartreuse3") , plwd=3, plty=1 ) 

Figure 4

Panel A

Idents(T.Seurat.spleen) <- "manualclusters"
T.Seurat.spleenbar <- subset(T.Seurat.spleen,  idents = c("0,5","9","1","11","19")) #to only keep cluster needed for the plot
data3 <- data.frame(prop.table(t(prop.table(table(T.Seurat.spleenbar@meta.data$HTO,T.Seurat.spleenbar@meta.data$manualclusters),1)),1)*100)

#order cluster level
data3$Var1 <- factor(data3$Var1, levels = c("0,5","9","1","11","19"))

cellnumber <- data.frame(colSums(table(T.Seurat.spleen@meta.data$HTO,T.Seurat.spleen@meta.data$manualclusters)) )
cellnumber$cluster <- rownames(cellnumber)
row_order <-c("0,5","9","1","11","19")
cellnumber <- cellnumber[row_order,]

Cluster <- data3$Var1
HTO <- data3$Var2
Percentage <- data3$Freq
text <- cellnumber$colSums.table.T.Seurat.spleen.meta.data.HTO..T.Seurat.spleen.meta.data.manualclusters..
# Stacked bar plot
cols <- c("Myc- PTEN- spleen" = "#FF99FF", "MYC- spleen" = "coral1", "PTEN- spleen" = "cyan3", "WT spleen" = "chartreuse3")

ggplot(data3, aes(fill=HTO, y=Percentage, x=Cluster)) + 
    geom_bar(position="stack", stat="identity", width=0.7)+
   xlab("Splenic Clusters")+ylab("Percentage")+ theme(legend.position="bottom")+scale_fill_manual(values =cols, labels=c("Myc Pten","Myc","Pten","WT")) +theme_light()+geom_hline(yintercept=c(25,50,75), linetype="dashed", color = "grey60")+ annotate("text", x = c(1,2,3,4,5), y=103, label = c(text))

Panel B

# On cluster 11 - cd8 memory
C11Ctrl <-rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-ctrl" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11Ctrl <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11Ctrl])
C11Pt <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-P" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11Pt <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11Pt])
C11MP <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-MP" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11MP <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11MP])
C11M <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-M" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11M <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11M])
#on cluster 19 - cd8 eff term
C19Ctrl <-rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-ctrl" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19Ctrl <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19Ctrl])
C19Pt <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-P" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19Pt <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19Pt])
C19MP <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-MP" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19MP <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19MP])
C19M <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-M" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19M <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19M])
#on cluster 1
C1Ctrl <-rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-ctrl" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1Ctrl <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1Ctrl])
C1Pt <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-P" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1Pt <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1Pt])
C1MP <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-MP" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1MP <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1MP])
C1M <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-M" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1M <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1M])


l1 <- c("1","1","1","1","11","11","11","11","19","19","19","19")
l2 <- c("Ctrl","Pten","Myc","MycPten","Ctrl","Pten","Myc","MycPten","Ctrl","Pten","Myc","MycPten")
l3 <- c(mC1Ctrl,mC1Pt,mC1M,mC1MP,mC11Ctrl,mC11Pt,mC11M,mC11MP,mC19Ctrl,mC19Pt,mC19M,mC19MP)

tableauYFP <- data.frame(Cluster = l1, Genotypes =l2) 
tableauYFP <- cbind(tableauYFP,Values = l3)


tableauYFP$Cluster <- factor(tableauYFP$Cluster,levels = c("1","11","19"))
tableauYFP$Genotypes <- factor(tableauYFP$Genotypes,levels = c("MycPten","Myc","Pten","Ctrl"))

ggplot(tableauYFP, aes(x = Cluster, Genotypes)) +
        geom_tile(aes(fill = Values)) +
        scale_fill_gradient2( mid='yellow', high='red',limits=c(0,max(tableauYFP$Values)))+ theme_classic(base_size=20)

Supplementary 2

FeaturePlot(T.Seurat, features = "Myc",cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"),order=T)

Supplementary 3

Panel A

Idents(T.Seurat) <- "integrated_snn_res.1.8"
#DGE between our two CD8 naive clusters
dgecd8_data <- read.table(paste(WORKING_DIR, "/02_Seurat_analysis/01_Script/dgeCD8data.txt",sep=""), sep = "\t")
# bar plot
#add abs value to table
dgecd8_data$abs <- abs(dgecd8_data$avg_logFC) 

dgecd8_data$genename <- rownames(dgecd8_data)
# Select markers for plotting on a Heatmap 
markers.use=subset(dgecd8_data, p_val_adj<1e-50 & abs>0.20)
dfcd8markers <-markers.use[order(markers.use$avg_logFC),]

dfcd8markers$genename <- factor(dfcd8markers$genename, levels = dfcd8markers$genename[order(dfcd8markers$avg_logFC)])
dfcd8markers$logpval <- log10(dfcd8markers$p_val_adj)
ggplot(dfcd8markers, aes(x = dfcd8markers$genename, y = dfcd8markers$avg_logFC, fill = logpval)) +   # Fill column
                              geom_bar(stat = "identity", width = .6) +   # draw the bars
                              ylim(-1.2,1.2)+
                              labs(title="DGE - Cluster 1 vs 4 (Cd8 naive)",y ="Log fold change", x = "Genes differentially expressed") +
                              theme_tufte() +  # Tufte theme from ggfortify
                              theme(plot.title = element_text(hjust = .5),axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1), 
                                    axis.ticks = element_blank()) +
                               scale_fill_gradient2(low='red', mid='orange', high='blue',midpoint = -120, breaks=c(-52,-120,-200),labels=c("-50","-120","-200"))+coord_flip() # Flip axes

Panel B

Idents(T.Seurat) <- "integrated_snn_res.1.8"
#DGE between 0 and 12
dgecd4_data <- read.table(paste(WORKING_DIR, "/02_Seurat_analysis/01_Script/dgeCD4data.txt",sep=""), sep = "\t")
# bar plot
#add abs value to table
dgecd4_data$abs <- abs(dgecd4_data$avg_logFC) 

dgecd4_data$genename <- rownames(dgecd4_data)
# Select markers for plotting on a Heatmap 
markers.use=subset(dgecd4_data,p_val_adj<1e-10 & abs>0.2)
dfcd4markers <-markers.use[order(markers.use$avg_logFC),]

dfcd4markers$genename <- factor(dfcd4markers$genename, levels = dfcd4markers$genename[order(dfcd4markers$avg_logFC)])
dfcd4markers$logpval <- log10(dfcd4markers$p_val_adj)
ggplot(dfcd4markers, aes(x = dfcd4markers$genename, y = dfcd4markers$avg_logFC, fill = logpval)) +   # Fill column
                              geom_bar(stat = "identity", width = .6) +   # draw the bars
                              ylim(-1.2,1.2)+
                              labs(title="DGE - Cluster 0 vs 12 (Cd4 naive)",y ="Log fold change", x = "Genes differentially expressed") +
                              theme_tufte() +  # Tufte theme from ggfortify
                              theme(plot.title = element_text(hjust = .5),axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1), 
                                    axis.ticks = element_blank()) +
                               scale_fill_gradient2(low='red', mid='orange', high='blue',midpoint = -40, breaks=c(-12,-40,-57),labels=c("-10","-40","-60"))+ coord_flip() # Flip axes

Panel C

Idents(T.Seurat) <- "integrated_snn_res.1.8"

# get all gene name express in our cells as background
background <- T.Seurat@assays$RNA@meta.features
backgroundrow <- rownames(background)
genecomprow <- read.table(paste(WORKING_DIR, "/02_Seurat_analysis/01_Script/cluster1v4.txt",sep=""), sep = "\t")
genecomprow$x = as.character(genecomprow$x)
genecomprow <- genecomprow[,1]

CPenrich <- enrichGO(gene= genecomprow, OrgDb = 'org.Mm.eg.db', ont="BP",keyType = "SYMBOL",universe = backgroundrow) # org.Mm.eg.db genome mouse
#head (CPenrich)
dotplot(CPenrich, showCategory=15,color = "p.adjust",x="count") #+ coord_flip()+theme(axis.text.x = element_text(angle = 90, hjust = 1))

Panel D

genecomprow <- read.table(paste(WORKING_DIR, "/02_Seurat_analysis/01_Script/cluster0vs12.txt",sep=""), sep = "\t")
genecomprow$x = as.character(genecomprow$x)
genecomprow <- genecomprow[,1]
####


CPenrich <- enrichGO(gene= genecomprow, OrgDb = 'org.Mm.eg.db', ont="BP",keyType = "SYMBOL",universe = backgroundrow) # org.Mm.eg.db genome mouse
dotplot(CPenrich, showCategory=15,color = "p.adjust",x="count")+ scale_y_discrete(labels=function(x)str_wrap(x, width=40))

Supplementary 4

Panel A

#DOT plot eyFP and TGD on CD8 effector and memory
Idents(T.Seurat.spleen) <- "integrated_snn_res.1.8"
CD8sub <- subset(T.Seurat.spleen, idents = c("11","19","13"))
Idents(CD8sub) <- "MULTI_ID"
CD8sub@active.ident <- factor(CD8sub@active.ident,levels=c("Spleen-M","Spleen-MP","Spleen-ctrl","Spleen-P"))
#levels(CD8sub)
DotPlot(CD8sub, dot.scale = 8,features = c("Tcrg-C1","Trdc","Trbc2","Trac","eYFP") ) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red")+ ggtitle("CD8 memory and effector clusters")

LS0tCnRpdGxlOiAiRmlndXJlIgphdXRob3I6ICJNYXRoaXMiCmRhdGU6ICIxMC8wNS8yMDIxIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlCi0tLQoKVGhpcyBSbWFya2Rvd24gY29udGFpbiBjb2RlIHRvIG9idGFpbiBhbGwgcGxvdCBuZWNlc3NhcnkgdG8gcHJvZHVjZSBvdXIgYmlvaW5mb3JtYXRpY2FsIHJlbGF0ZWQgZmlndXJlcy4gRmluYWwgZmlndXJlIGFub3RhdGlvbiBhbmQgbGF5b3V0IHdlcmUgdGhlbiBwcm9kdWNlIHdpdGggaW5rc2NhcGUuCgpgYGB7cixpbmNsdWRlPUZBTFNFfQpPVVRQVVRfUEFUSCA8LSAocGFzdGUwKFdPUktJTkdfRElSLCIvMDJfU2V1cmF0X2FuYWx5c2lzLzAyX091dHB1dC8iKSkKCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGZtc2IpCmxpYnJhcnkoZ3JhcGhpY3MpCmxpYnJhcnkoZ2d0aGVtZXMpCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQpsaWJyYXJ5IChzdHJpbmdyKQoKYGBgCgpgYGB7cixpbmNsdWRlPUZBTFNFfQojWmVub2RvIHN1Ym1pdGVkIG9iamVjdHMgYXJlIG5vdCBjb21wbGV0ZSwgYW5kIGFsbCB0aGUgZmlndXJlcyBjYW4ndCBiZSBwcm9kdWNlIGlmIEV4cGVyaW1lbnRfYW5hbHlzaXMucm1kIHdhc24ndCBydW4gYmVmb3JlLiBUaGlzIGNodW5rIGNvcnJlY3QgdGhlIHByb2JsZW0KCmlmKCEgZmlsZS5leGlzdHMocGFzdGUwKE9VVFBVVF9QQVRILCAiVC1TZXVyYXQtbWVyZ2VkX2ZpbmFsIiwiLlJvYmoiKSkpewpwcmludCgiQ3JlYXRpbmcgZmluYWwgUiBvYmplY3RzIGZyb20gRXhwZXJpbWVudF9BbmFseXNpcy5SbWQgdG8gcHJvZHVjZSBmaWd1cmVzIikKIyMgQ1JFQVRFIEZJTkFMIE9CSkVDVAogICMgVGh5bWljIGFuZCBzcGxlbmljIG9iagogICAgbG9hZChwYXN0ZTAoT1VUUFVUX1BBVEgsICJULVNldXJhdC1tZXJnZWRfY2xlYW4tc3Vic2V0IiwiLlJvYmoiKSkKICAgIElkZW50cyhULlNldXJhdCkgPC0gIkhUTyIKICAgIFQuU2V1cmF0LnRoeW11cyA8LSBzdWJzZXQoVC5TZXVyYXQsIGlkZW50cyA9IGMoIk15Yy0gUFRFTi0gdGh5bXVzIiwiTVlDLSB0aHltdXMiLCJQVEVOLSB0aHltdXMiLCJXVCB0aHltdXMiKSkKICAgIGEgPC0gdChtYXJnaW4udGFibGUodGFibGUoVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRIVE8sVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44KSwyKSkKICAgIFQuU2V1cmF0LnNwbGVlbiA8LSBzdWJzZXQoVC5TZXVyYXQsIGlkZW50cyA9IGMoIk15Yy0gUFRFTi0gc3BsZWVuIiwiTVlDLSBzcGxlZW4iLCJQVEVOLSBzcGxlZW4iLCJXVCBzcGxlZW4iKSkKICAgIGIgPC0gdChtYXJnaW4udGFibGUodGFibGUoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRIVE8sVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44KSwyKSkKICAgIGMgPC0gdCgoYS8oYStiKSoxMDApKQoKICAgICNUaHltaWMgcG9wdWxhdGlvbnMKICAgIHRoeW11cy5jbHVzdGVycyA8LSByb3duYW1lcyhhcy5kYXRhLmZyYW1lKGNbd2hpY2goY1ssMV0+MjUpLF0pKQogICAgSWRlbnRzKFQuU2V1cmF0LnRoeW11cykgPC0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiCiAgICBULlNldXJhdC50aHltdXMgPC0gc3Vic2V0KFQuU2V1cmF0LnRoeW11cywgaWRlbnRzID0gdGh5bXVzLmNsdXN0ZXJzKQogICAgRGltUGxvdChULlNldXJhdC50aHltdXMpK2dndGl0bGUoIlRoeW1pYyBzdWJzZXQiKQogICAgCiAgICBzcGxlZW4uY2x1c3RlcnMgPC0gcm93bmFtZXMoYXMuZGF0YS5mcmFtZShjW3doaWNoKGNbLDFdPDc1KSxdKSkKICAgIElkZW50cyhULlNldXJhdC5zcGxlZW4pIDwtICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IgogICAgVC5TZXVyYXQuc3BsZWVuIDwtIHN1YnNldChULlNldXJhdC5zcGxlZW4sIGlkZW50cyA9IHNwbGVlbi5jbHVzdGVycykKICAgIERpbVBsb3QoVC5TZXVyYXQuc3BsZWVuKStnZ3RpdGxlKCJTcGxlbmljIHN1YnNldCIpCiAgICAKICAjIEFkZCB0aXNzdWUgYW5ub3RhdGlvbiBmb3IgZmluYWwgbWVyZ2Ugb2JqZWN0CiAgICBzcGxlZW4uY2VsbHMgPC0gYyhyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1jdHJsIiApKSxyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1NIiApKSxyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1NUCIgKSkscm93Lm5hbWVzKHN1YnNldChULlNldXJhdEBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJTcGxlZW4tUCIgKSkpCgogICAgdGh5bXVzLmNlbGxzIDwtIGMocm93Lm5hbWVzKHN1YnNldChULlNldXJhdEBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtY3RybCIgKSkscm93Lm5hbWVzKHN1YnNldChULlNldXJhdEBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtTSIgKSkscm93Lm5hbWVzKHN1YnNldChULlNldXJhdEBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtTVAiICkpLHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiVGh5bXVzLVAiICkpKQoKICAgIFQuU2V1cmF0QG1ldGEuZGF0YSR0aXNzdWUgPSAibm90aGluZyIKICAgIFQuU2V1cmF0QG1ldGEuZGF0YVtzcGxlZW4uY2VsbHMsXSR0aXNzdWUgPSAiU3BsZWVuIgogICAgVC5TZXVyYXRAbWV0YS5kYXRhW3RoeW11cy5jZWxscyxdJHRpc3N1ZSA9ICJUaHltdXMiCiAgIyBBZGQgbWFudWFsIGNsdXN0ZXJpbmcgYW5ub3RhdGlvbiBmb3IgZmluYWwgbWVyZ2Ugb2JqZWN0CiAgICAjUmVncm91cCB0aHltaWMgY2x1c3RlcnMKICAgICNTaW1pbGFyIGNsdXN0ZXIgYXJlIGFubm90YXRlIGFzIG9uZQogICAgSWRlbnRzKFQuU2V1cmF0LnRoeW11cykgPC0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiCiAgICBULlNldXJhdC50aHltdXNAbWV0YS5kYXRhJG1hbnVhbGNsdXN0ZXJzID0gIm5vdGhpbmciCiAgICBULlNldXJhdC50aHltdXNAbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQudGh5bXVzLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMjIiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjIyIgogICAgVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnRoeW11cywgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gIjIxIiksXSRtYW51YWxjbHVzdGVycyA9ICIyMSIKICAgIFQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC50aHltdXMsIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9IGMoIjIwIiwiMTgiLCIxNCIpKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjIwLDE4LDE0IgogICAgVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnRoeW11cywgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gYygiOCIsIjIiLCIzIiwiMjMiKSksXSRtYW51YWxjbHVzdGVycyA9ICI4LDIsMywyMyIKICAgIFQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC50aHltdXMsIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICI2IiksXSRtYW51YWxjbHVzdGVycyA9ICI2IgogICAgVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnRoeW11cywgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gIjciKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjciCiAgICBULlNldXJhdC50aHltdXNAbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQudGh5bXVzLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSBjKCIxMCIsIjE2IikpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTAsMTYiCiAgICBULlNldXJhdC50aHltdXNAbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQudGh5bXVzLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMTciKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjE3IgogICAgCiAgICAjUmVncm91cCBzcGxlbmljIGNsdXN0ZXJzCiAgICAjU2ltaWxhciBjbHVzdGVyIGFyZSBhbm5vdGF0ZSBhcyBvbmUKICAgIElkZW50cyhULlNldXJhdC5zcGxlZW4pIDwtICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IgogICAgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRtYW51YWxjbHVzdGVycyA9ICJub3RoaW5nIgogICAgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnNwbGVlbiwgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gIjQiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjQiCiAgICBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMSIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMSIKICAgIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICI5IiksXSRtYW51YWxjbHVzdGVycyA9ICI5IgogICAgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnNwbGVlbiwgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gIjEyIiksXSRtYW51YWxjbHVzdGVycyA9ICIxMiIKICAgIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICIxMSIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTEiCiAgICBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMTkiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjE5IgogICAgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnNwbGVlbiwgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gIjEzIiksXSRtYW51YWxjbHVzdGVycyA9ICIxMyIKICAgIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICIxNyIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTciCiAgICBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSBjKCIxMCIsIjE2IikpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTAsMTYiCiAgICBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMTUiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjE1IgogICAgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnNwbGVlbiwgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gYygiMCIsIjUiKSksXSRtYW51YWxjbHVzdGVycyA9ICIwLDUiCiAgICAKICAgICNTYXZlIGZpbmFsIG9iamVjdCB1c2VkIGFmdGVyIGluIHRoaXMgY29kZSBhbmQgZm9yIGZpZ3VyZS5SbWQKICAgIHNhdmUoVC5TZXVyYXQsIGZpbGUgPSBwYXN0ZTAoT1VUUFVUX1BBVEgsICJULVNldXJhdC1tZXJnZWRfZmluYWwiLCAiLlJvYmoiKSkKICAgIHNhdmUoVC5TZXVyYXQuc3BsZWVuLCBmaWxlID0gcGFzdGUwKE9VVFBVVF9QQVRILCAiVC1TZXVyYXQtc3BsZWVuX2ZpbmFsIiwgIi5Sb2JqIikpCiAgICBzYXZlKFQuU2V1cmF0LnRoeW11cywgZmlsZSA9IHBhc3RlMChPVVRQVVRfUEFUSCwgIlQtU2V1cmF0LXRoeW11c19maW5hbCIsICIuUm9iaiIpKQogICAgCn1lbHNlewpwcmludCgiTG9hZGluZyBmaW5hbCBSIG9iamVjdHMgcHJvZHVjZSBpbiBFeHBlcmltZW50X0FuYWx5c2lzLlJtZCB0byBwcm9kdWNlIGZpZ3VyZXMiKQpsb2FkKHBhc3RlMChPVVRQVVRfUEFUSCwgIlQtU2V1cmF0LW1lcmdlZF9maW5hbCIsIi5Sb2JqIikpCmxvYWQocGFzdGUwKE9VVFBVVF9QQVRILCAiVC1TZXVyYXQtc3BsZWVuX2ZpbmFsIiwiLlJvYmoiKSkKbG9hZChwYXN0ZTAoT1VUUFVUX1BBVEgsICJULVNldXJhdC10aHltdXNfZmluYWwiLCIuUm9iaiIpKQp9CmBgYAoKIyMjIEZJR1VSRSAyIHsudGFic2V0fQojIyMjIFBhbmVsIEEKYGBge3J9CiMgSGlnaGxpZ2h0IHNwZWNpZmljIEhUTyAgNng0CklkZW50cyhULlNldXJhdCkgPC0gIk1VTFRJX0lEIgpjZWxsTSA8LSBXaGljaENlbGxzKFQuU2V1cmF0LCBpZGVudHMgPSBjKCJTcGxlZW4tTSIsIlRoeW11cy1NIikgKQpwbG90TSA8LSBEaW1QbG90KFQuU2V1cmF0LGNlbGxzLmhpZ2hsaWdodCA9IGNlbGxNLHNpemVzLmhpZ2hsaWdodCA9IDAuNSxjb2xzID0gImdyZXk4MCIsIGNvbHMuaGlnaGxpZ2h0ID0gImNvcmFsMiIscHQuc2l6ZSA9IDAuNSkrIE5vTGVnZW5kKCkrTm9BeGVzKCkKCmNlbGxjdHJsIDwtIFdoaWNoQ2VsbHMoVC5TZXVyYXQsIGlkZW50cyA9IGMoIlNwbGVlbi1jdHJsIiwiVGh5bXVzLWN0cmwiKSApCnBsb3RDIDwtIERpbVBsb3QoVC5TZXVyYXQsY2VsbHMuaGlnaGxpZ2h0ID0gY2VsbGN0cmwsc2l6ZXMuaGlnaGxpZ2h0ID0gMC41LGNvbHMgPSAiZ3JleTgwIiwgY29scy5oaWdobGlnaHQ9ImNoYXJ0cmV1c2U0IixwdC5zaXplID0gMC41KSsgTm9MZWdlbmQoKStOb0F4ZXMoKQoKY2VsbE1QIDwtIFdoaWNoQ2VsbHMoVC5TZXVyYXQsIGlkZW50cyA9IGMoIlNwbGVlbi1NUCIsIlRoeW11cy1NUCIpICkKcGxvdE1QIDwtIERpbVBsb3QoVC5TZXVyYXQsY2VsbHMuaGlnaGxpZ2h0ID0gY2VsbE1QLHNpemVzLmhpZ2hsaWdodCA9IDAuNSxjb2xzID0gImdyZXk4MCIsIGNvbHMuaGlnaGxpZ2h0PSIjQ0MwMDk5IixwdC5zaXplID0gMC41KSsgTm9MZWdlbmQoKStOb0F4ZXMoKQoKY2VsbFAgPC0gV2hpY2hDZWxscyhULlNldXJhdCwgaWRlbnRzID0gYygiU3BsZWVuLVAiLCJUaHltdXMtUCIpICkKcGxvdFAgPC0gRGltUGxvdChULlNldXJhdCxjZWxscy5oaWdobGlnaHQgPSBjZWxsUCxzaXplcy5oaWdobGlnaHQgPSAwLjUsY29scyA9ICJncmV5ODAiLCBjb2xzLmhpZ2hsaWdodD0iZGVlcHNreWJsdWUzIixwdC5zaXplID0gMC41KSsgTm9MZWdlbmQoKStOb0F4ZXMoKQoKI3RoeW11cyB2cyByYXRlIGZpZ3VyZQpwbG90b3JnYW4gPC0gRGltUGxvdChULlNldXJhdCwgZ3JvdXAuYnkgPSAidGlzc3VlIixjb2xzPWMoImRhcmtnb2xkZW5yb2QxIiwiZGFya3JlZCIpLHB0LnNpemUgPSAwLjUpKyBOb0xlZ2VuZCgpK05vQXhlcygpCmBgYAoKYGBge3IsZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDEwfQpwYW5BIDwtIGdyaWQuYXJyYW5nZShwbG90TSwgcGxvdFAscGxvdE1QLHBsb3RDLHBsb3RvcmdhbiwgbnJvdyA9IDMpCmBgYAoKIyMjIyBQYW5lbCBCCmBgYHtyIHBhbmVsQixmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gNiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KSWRlbnRzKFQuU2V1cmF0KSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKdW1hcGNvbHMgPC0gYygiIzk5QTZFNyIsIiNFM0IxRDYiLCIjRjc4NzU0IiwiI0Y5NEExNyIsIiNDQzc5QjciLCIjNjQ3N0Q4IiwiIzkxOTI5NiIsIiNDRjA2M0EiLCIjRkVBOTgxIiwiIzU1QUM3QyIsIiM1RjQwOTAiLCIjRDEzQTdDIiwiIzEzMzJEMCIsIiNFQzAwNjciLCIjRkI3MTBEIiwiIzA5QjMyOSIsIiNCMjNBQ0UiLCIjN0ExRTQ1IiwiI0ZCOTIwRCIsIiNGRjM1QUMiLCIjRkJBRjBEIiwiI0VDQjkwQyIsIiNGRkRBMEQiLCIjRTIyNjExIikKCgpEaW1QbG90KFQuU2V1cmF0LCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBwdC5zaXplID0gMSxjb2xzID0gdW1hcGNvbHMpKyBOb0xlZ2VuZCgpCnBhbkIgPC0gRGltUGxvdChULlNldXJhdCwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgcHQuc2l6ZSA9IDEsY29scyA9IHVtYXBjb2xzKSsgTm9MZWdlbmQoKQpgYGAKCiMjIyMgUGFuZWwgQwpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI0RvdHBsb3QgdGh5bXVzCklkZW50cyhULlNldXJhdC50aHltdXMpIDwtICJtYW51YWxjbHVzdGVycyIKVC5TZXVyYXQudGh5bXVzQGFjdGl2ZS5pZGVudCA8LSBmYWN0b3IoVC5TZXVyYXQudGh5bXVzQGFjdGl2ZS5pZGVudCxsZXZlbHM9YygiMjIiLCIyMSIsIjIwLDE4LDE0IiwiOCwyLDMsMjMiLCI3IiwiNiIsIjEwLDE2IiwiMTciKSkKbGV2ZWxzKFQuU2V1cmF0LnRoeW11cykKCmRvdHBsb3R0aHltIDwtIERvdFBsb3QoVC5TZXVyYXQudGh5bXVzLCBkb3Quc2NhbGUgPSAxNCxmZWF0dXJlcyA9IGMoInBlcmNlbnQubWl0byIsIkJtZiIsIlRycDUzaW5wMSIsIlRveDIiLCJDZDUiLCJDZDY5IiwiQ2QyNyIsIlJhZzEiLCJSYWcyIiwiQ2Q0IiwiQ2Q4YSIsIkNkOGIxIiwiTWtpNjciLCJDZGsxIiwiUHRjcmEiLCJJbDJyYSIsIkNkMzQiKSkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdyA9ICJzdGVlbGJsdWUiLCBtaWQgPSAid2hpdGUiLCBoaWdoID0gInJlZCIpICsgY29vcmRfZmxpcCgpKyB0aGVtZSgKICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwKICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsYW5nbGUgPSA5MCksCiAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksCiAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImdyZXk2NSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiKSwKICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGxpbmV0eXBlID0gJ3NvbGlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTU1IikpCiNkb3Qgc2NhbGUgd2FzIDggYnV0IGNoYW5nZSBmb3Igcm1hcmtkb3duIG91dHB1dApgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIERvdHBsb3Qgc3BsZWVuCklkZW50cyhULlNldXJhdC5zcGxlZW4pIDwtICJtYW51YWxjbHVzdGVycyIKClQuU2V1cmF0LnNwbGVlbkBhY3RpdmUuaWRlbnQgPC0gZmFjdG9yKFQuU2V1cmF0LnNwbGVlbkBhY3RpdmUuaWRlbnQsbGV2ZWxzPWMoIjEwLDE2IiwiMSIsIjQiLCIwLDUiLCIxMiIsIjE1IiwiOSIsIjE3IiwiMTMiLCIxMSIsIjE5IikpCmRvdHBsb3RzcGxlZW4gPC0gRG90UGxvdChULlNldXJhdC5zcGxlZW4sIGRvdC5zY2FsZSA9IDE0LCBmZWF0dXJlcz0gYygiRm94cDMiLCJBZXMiLCJBbnhhMSIsIkd6bWEiLCJDY2w1IiwiQ3hjcjMiLCJTZWxsIiwiUzFwcjEiLCJDY3I3IiwiVHJkYyIsIlRjcmctQzQiLCJUY3JnLUMyIiwiVGNyZy1DMSIsIlRyYmMyIiwiVHJiYzEiLCJUcmFjIiwiQ2Q4YjEiLCJDZDQiKSkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdyA9ICJzdGVlbGJsdWUiLCBtaWQgPSAid2hpdGUiLCBoaWdoID0gInJlZCIpICsgdGhlbWUoCiAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwKICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsYW5nbGUgPSA5MCksCiAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksCiAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImdyZXk2NSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiKSwKICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGxpbmV0eXBlID0gJ3NvbGlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTU1IikpICsgY29vcmRfZmxpcCgpCiNkb3Qgc2NhbGUgd2FzIDggYnV0IGNoYW5nZSBmb3Igcm1hcmtkb3duIG91dHB1dApgYGAKCmBgYHtyLGZpZy53aWR0aCA9IDIwLCBmaWcuaGVpZ2h0ID0gMTB9CiNDb21iaW5lIGRvdHBsb3QKcGFuQyA8LSBncmlkLmFycmFuZ2UoZG90cGxvdHRoeW0sZG90cGxvdHNwbGVlbiwgbmNvbCA9IDIpCmBgYAoKIyMjIyBQYW5lbCBECmBgYHtyfQojY2hlY2sgcGFyCnBhcihvbWEgPSBjKDAsIDAsIDAsIDApKQpwYXIobWFyID0gYygwLDEsMCwxKSkKcGFyKG1mcm93PWMoMSwyKSkKI2NoZWNrIGdlbm90eXBlIHByb3BvcnRpb24gaW4gZWFjaCBzcGxlZW4gY2x1c3RlcnMKCmRmIDwtIGFzLmRhdGEuZnJhbWUoYXMuZGF0YS5mcmFtZS5tYXRyaXgodChwcm9wLnRhYmxlKHRhYmxlKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkSFRPLFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkbWFudWFsY2x1c3RlcnMpLDEpKjEwMCkpKQpkZiRjbHVzdGVyID0gcm93bmFtZXMoZGYpCmRmMjwtYXMuZGF0YS5mcmFtZSh0KGNiaW5kKHJlcCg2MCwxMSkscmVwKDAsMTEpLGRmKVssMTo2XSkpCnJvd25hbWVzKGRmMlsxOjIsXSkgPC0gYygiNjAiLCIwIikKCiNvcmRlciBkYXRhIGZyYW1lCmRmMiA8LSBkZjJbYygiMTAsMTYiLCIxOSIsIjExIiwiMTMiLCIxNyIsIjkiLCIxNSIsIjEyIiwiMCw1IiwiNCIsIjEiKV0KCnJhZGFyc3BsZWVuIDwtIHJhZGFyY2hhcnQoZGYyLCBjZ2xjb2w9ImdyZXkiLCBjZ2x0eT0xICxjZ2x3ZD0wLjgsIHZsY2V4PTAuOCwgcGNvbD1jKCIjRkY5OUZGIiwiY29yYWwxIiwiY3lhbjMiLCJjaGFydHJldXNlMyIpICwgcGx3ZD0zLCBwbHR5PTEgLGNheGlzbGFiZWxzPXBhc3RlKHNlcShmcm9tID0gMCx0byA9IDYwLGJ5ID0gMTUpLCIlIiksIGF4aXNsYWJjb2wgPSAiZ3JleTQwIiwgYXhpc3R5cGUgPSAwKQoKI2NoZWNrIGdlbm90eXBlIHByb3BvcnRpb24gaW4gZWFjaCB0aHltaWMgY2x1c3RlcgpkZiA8LSAgYXMuZGF0YS5mcmFtZShhcy5kYXRhLmZyYW1lLm1hdHJpeCh0KHByb3AudGFibGUodGFibGUoVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRIVE8sVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRtYW51YWxjbHVzdGVycyksMSkqMTAwKSkpCmRmJGNsdXN0ZXIgPSByb3duYW1lcyhkZikKZGYyPC1hcy5kYXRhLmZyYW1lKHQoY2JpbmQocmVwKDY1LDgpLHJlcCgwLDgpLGRmKVssMTo2XSkpCnJvd25hbWVzKGRmMlsxOjIsXSkgPC0gYygiNjUiLCIwIikKCiNvcmRlcgpkZjIgPC0gZGYyW2MoIjIyIiwiMTciLCIxMCwxNiIsIjYiLCI3IiwiOCwyLDMsMjMiLCIyMCwxOCwxNCIsIjIxIildCgoKcmFkYXJ0aHltdXMgPC0gcmFkYXJjaGFydChkZjIsIGNnbGNvbD0iZ3JleSIsIGNnbHR5PTEsY2F4aXNsYWJlbHM9cGFzdGUoc2VxKDAsNzAsMTcuNSksIiUiKSwgYXhpc3R5cGUgPSAwLGF4aXNsYWJjb2w9ImdyZXk0MCIsIGNnbHdkPTAuOCwgdmxjZXg9MC44LCBwY29sPWMoIiNGRjk5RkYiLCJjb3JhbDEiLCJjeWFuMyIsImNoYXJ0cmV1c2UzIikgLCBwbHdkPTMsIHBsdHk9MSApIAoKYGBgCgpgYGB7cixpbmNsdWRlPUZBTFNFfQojcmVzZXQgcGFyCmRldi5vZmYoKSAgCmBgYAoKIyMjIEZpZ3VyZSA0IHsudGFic2V0fQojIyMjIFBhbmVsIEEKYGBge3J9CklkZW50cyhULlNldXJhdC5zcGxlZW4pIDwtICJtYW51YWxjbHVzdGVycyIKVC5TZXVyYXQuc3BsZWVuYmFyIDwtIHN1YnNldChULlNldXJhdC5zcGxlZW4sICBpZGVudHMgPSBjKCIwLDUiLCI5IiwiMSIsIjExIiwiMTkiKSkgI3RvIG9ubHkga2VlcCBjbHVzdGVyIG5lZWRlZCBmb3IgdGhlIHBsb3QKZGF0YTMgPC0gZGF0YS5mcmFtZShwcm9wLnRhYmxlKHQocHJvcC50YWJsZSh0YWJsZShULlNldXJhdC5zcGxlZW5iYXJAbWV0YS5kYXRhJEhUTyxULlNldXJhdC5zcGxlZW5iYXJAbWV0YS5kYXRhJG1hbnVhbGNsdXN0ZXJzKSwxKSksMSkqMTAwKQoKI29yZGVyIGNsdXN0ZXIgbGV2ZWwKZGF0YTMkVmFyMSA8LSBmYWN0b3IoZGF0YTMkVmFyMSwgbGV2ZWxzID0gYygiMCw1IiwiOSIsIjEiLCIxMSIsIjE5IikpCgpjZWxsbnVtYmVyIDwtIGRhdGEuZnJhbWUoY29sU3Vtcyh0YWJsZShULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJEhUTyxULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJG1hbnVhbGNsdXN0ZXJzKSkgKQpjZWxsbnVtYmVyJGNsdXN0ZXIgPC0gcm93bmFtZXMoY2VsbG51bWJlcikKcm93X29yZGVyIDwtYygiMCw1IiwiOSIsIjEiLCIxMSIsIjE5IikKY2VsbG51bWJlciA8LSBjZWxsbnVtYmVyW3Jvd19vcmRlcixdCgpDbHVzdGVyIDwtIGRhdGEzJFZhcjEKSFRPIDwtIGRhdGEzJFZhcjIKUGVyY2VudGFnZSA8LSBkYXRhMyRGcmVxCnRleHQgPC0gY2VsbG51bWJlciRjb2xTdW1zLnRhYmxlLlQuU2V1cmF0LnNwbGVlbi5tZXRhLmRhdGEuSFRPLi5ULlNldXJhdC5zcGxlZW4ubWV0YS5kYXRhLm1hbnVhbGNsdXN0ZXJzLi4KIyBTdGFja2VkIGJhciBwbG90CmNvbHMgPC0gYygiTXljLSBQVEVOLSBzcGxlZW4iID0gIiNGRjk5RkYiLCAiTVlDLSBzcGxlZW4iID0gImNvcmFsMSIsICJQVEVOLSBzcGxlZW4iID0gImN5YW4zIiwgIldUIHNwbGVlbiIgPSAiY2hhcnRyZXVzZTMiKQoKZ2dwbG90KGRhdGEzLCBhZXMoZmlsbD1IVE8sIHk9UGVyY2VudGFnZSwgeD1DbHVzdGVyKSkgKyAKICAgIGdlb21fYmFyKHBvc2l0aW9uPSJzdGFjayIsIHN0YXQ9ImlkZW50aXR5Iiwgd2lkdGg9MC43KSsKICAgeGxhYigiU3BsZW5pYyBDbHVzdGVycyIpK3lsYWIoIlBlcmNlbnRhZ2UiKSsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKStzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPWNvbHMsIGxhYmVscz1jKCJNeWMgUHRlbiIsIk15YyIsIlB0ZW4iLCJXVCIpKSArdGhlbWVfbGlnaHQoKStnZW9tX2hsaW5lKHlpbnRlcmNlcHQ9YygyNSw1MCw3NSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJncmV5NjAiKSsgYW5ub3RhdGUoInRleHQiLCB4ID0gYygxLDIsMyw0LDUpLCB5PTEwMywgbGFiZWwgPSBjKHRleHQpKQpgYGAKCiMjIyMgUGFuZWwgQgpgYGB7cn0KIyBPbiBjbHVzdGVyIDExIC0gY2Q4IG1lbW9yeQpDMTFDdHJsIDwtcm93bmFtZXMoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJE1VTFRJX0lEID09ICJTcGxlZW4tY3RybCIgJiBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjggPT0gIjExIixdKQptQzExQ3RybCA8LSBtZWFuKFQuU2V1cmF0LnNwbGVlbkBhc3NheXMkUk5BQGRhdGFbImVZRlAiLEMxMUN0cmxdKQpDMTFQdCA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1QIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMTEiLF0pCm1DMTFQdCA8LSBtZWFuKFQuU2V1cmF0LnNwbGVlbkBhc3NheXMkUk5BQGRhdGFbImVZRlAiLEMxMVB0XSkKQzExTVAgPC0gcm93bmFtZXMoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJE1VTFRJX0lEID09ICJTcGxlZW4tTVAiICYgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44ID09ICIxMSIsXSkKbUMxMU1QIDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzExTVBdKQpDMTFNIDwtIHJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLU0iICYgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44ID09ICIxMSIsXSkKbUMxMU0gPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMTFNXSkKI29uIGNsdXN0ZXIgMTkgLSBjZDggZWZmIHRlcm0KQzE5Q3RybCA8LXJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICYgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44ID09ICIxOSIsXSkKbUMxOUN0cmwgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMTlDdHJsXSkKQzE5UHQgPC0gcm93bmFtZXMoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJE1VTFRJX0lEID09ICJTcGxlZW4tUCIgJiBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjggPT0gIjE5IixdKQptQzE5UHQgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMTlQdF0pCkMxOU1QIDwtIHJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLU1QIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMTkiLF0pCm1DMTlNUCA8LSBtZWFuKFQuU2V1cmF0LnNwbGVlbkBhc3NheXMkUk5BQGRhdGFbImVZRlAiLEMxOU1QXSkKQzE5TSA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1NIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMTkiLF0pCm1DMTlNIDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzE5TV0pCiNvbiBjbHVzdGVyIDEKQzFDdHJsIDwtcm93bmFtZXMoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJE1VTFRJX0lEID09ICJTcGxlZW4tY3RybCIgJiBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjggPT0gIjEiLF0pCm1DMUN0cmwgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMUN0cmxdKQpDMVB0IDwtIHJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLVAiICYgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44ID09ICIxIixdKQptQzFQdCA8LSBtZWFuKFQuU2V1cmF0LnNwbGVlbkBhc3NheXMkUk5BQGRhdGFbImVZRlAiLEMxUHRdKQpDMU1QIDwtIHJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLU1QIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMSIsXSkKbUMxTVAgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMU1QXSkKQzFNIDwtIHJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLU0iICYgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44ID09ICIxIixdKQptQzFNIDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzFNXSkKCgpsMSA8LSBjKCIxIiwiMSIsIjEiLCIxIiwiMTEiLCIxMSIsIjExIiwiMTEiLCIxOSIsIjE5IiwiMTkiLCIxOSIpCmwyIDwtIGMoIkN0cmwiLCJQdGVuIiwiTXljIiwiTXljUHRlbiIsIkN0cmwiLCJQdGVuIiwiTXljIiwiTXljUHRlbiIsIkN0cmwiLCJQdGVuIiwiTXljIiwiTXljUHRlbiIpCmwzIDwtIGMobUMxQ3RybCxtQzFQdCxtQzFNLG1DMU1QLG1DMTFDdHJsLG1DMTFQdCxtQzExTSxtQzExTVAsbUMxOUN0cmwsbUMxOVB0LG1DMTlNLG1DMTlNUCkKCnRhYmxlYXVZRlAgPC0gZGF0YS5mcmFtZShDbHVzdGVyID0gbDEsIEdlbm90eXBlcyA9bDIpIAp0YWJsZWF1WUZQIDwtIGNiaW5kKHRhYmxlYXVZRlAsVmFsdWVzID0gbDMpCgoKdGFibGVhdVlGUCRDbHVzdGVyIDwtIGZhY3Rvcih0YWJsZWF1WUZQJENsdXN0ZXIsbGV2ZWxzID0gYygiMSIsIjExIiwiMTkiKSkKdGFibGVhdVlGUCRHZW5vdHlwZXMgPC0gZmFjdG9yKHRhYmxlYXVZRlAkR2Vub3R5cGVzLGxldmVscyA9IGMoIk15Y1B0ZW4iLCJNeWMiLCJQdGVuIiwiQ3RybCIpKQoKZ2dwbG90KHRhYmxlYXVZRlAsIGFlcyh4ID0gQ2x1c3RlciwgR2Vub3R5cGVzKSkgKwogICAgICAgIGdlb21fdGlsZShhZXMoZmlsbCA9IFZhbHVlcykpICsKICAgICAgICBzY2FsZV9maWxsX2dyYWRpZW50MiggbWlkPSd5ZWxsb3cnLCBoaWdoPSdyZWQnLGxpbWl0cz1jKDAsbWF4KHRhYmxlYXVZRlAkVmFsdWVzKSkpKyB0aGVtZV9jbGFzc2ljKGJhc2Vfc2l6ZT0yMCkKYGBgCgojIyMgU3VwcGxlbWVudGFyeSAyIHsudGFic2V0fQpgYGB7cn0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gIk15YyIsY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpLG9yZGVyPVQpCmBgYAoKCgoKIyMjIFN1cHBsZW1lbnRhcnkgMyB7LnRhYnNldH0KIyMjIyBQYW5lbCBBCmBgYHtyfQpJZGVudHMoVC5TZXVyYXQpIDwtICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IgojREdFIGJldHdlZW4gb3VyIHR3byBDRDggbmFpdmUgY2x1c3RlcnMKZGdlY2Q4X2RhdGEgPC0gcmVhZC50YWJsZShwYXN0ZShXT1JLSU5HX0RJUiwgIi8wMl9TZXVyYXRfYW5hbHlzaXMvMDFfU2NyaXB0L2RnZUNEOGRhdGEudHh0IixzZXA9IiIpLCBzZXAgPSAiXHQiKQojIGJhciBwbG90CiNhZGQgYWJzIHZhbHVlIHRvIHRhYmxlCmRnZWNkOF9kYXRhJGFicyA8LSBhYnMoZGdlY2Q4X2RhdGEkYXZnX2xvZ0ZDKSAKCmRnZWNkOF9kYXRhJGdlbmVuYW1lIDwtIHJvd25hbWVzKGRnZWNkOF9kYXRhKQojIFNlbGVjdCBtYXJrZXJzIGZvciBwbG90dGluZyBvbiBhIEhlYXRtYXAgCm1hcmtlcnMudXNlPXN1YnNldChkZ2VjZDhfZGF0YSwgcF92YWxfYWRqPDFlLTUwICYgYWJzPjAuMjApCmRmY2Q4bWFya2VycyA8LW1hcmtlcnMudXNlW29yZGVyKG1hcmtlcnMudXNlJGF2Z19sb2dGQyksXQoKZGZjZDhtYXJrZXJzJGdlbmVuYW1lIDwtIGZhY3RvcihkZmNkOG1hcmtlcnMkZ2VuZW5hbWUsIGxldmVscyA9IGRmY2Q4bWFya2VycyRnZW5lbmFtZVtvcmRlcihkZmNkOG1hcmtlcnMkYXZnX2xvZ0ZDKV0pCmRmY2Q4bWFya2VycyRsb2dwdmFsIDwtIGxvZzEwKGRmY2Q4bWFya2VycyRwX3ZhbF9hZGopCmBgYAoKYGBge3IsZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA4fQpnZ3Bsb3QoZGZjZDhtYXJrZXJzLCBhZXMoeCA9IGRmY2Q4bWFya2VycyRnZW5lbmFtZSwgeSA9IGRmY2Q4bWFya2VycyRhdmdfbG9nRkMsIGZpbGwgPSBsb2dwdmFsKSkgKyAgICMgRmlsbCBjb2x1bW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gLjYpICsgICAjIGRyYXcgdGhlIGJhcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWxpbSgtMS4yLDEuMikrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYnModGl0bGU9IkRHRSAtIENsdXN0ZXIgMSB2cyA0IChDZDggbmFpdmUpIix5ID0iTG9nIGZvbGQgY2hhbmdlIiwgeCA9ICJHZW5lcyBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQiKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lX3R1ZnRlKCkgKyAgIyBUdWZ0ZSB0aGVtZSBmcm9tIGdnZm9ydGlmeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUpLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCkpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0ncmVkJywgbWlkPSdvcmFuZ2UnLCBoaWdoPSdibHVlJyxtaWRwb2ludCA9IC0xMjAsIGJyZWFrcz1jKC01MiwtMTIwLC0yMDApLGxhYmVscz1jKCItNTAiLCItMTIwIiwiLTIwMCIpKStjb29yZF9mbGlwKCkgIyBGbGlwIGF4ZXMKYGBgCgoKIyMjIyBQYW5lbCBCCgpgYGB7cn0KSWRlbnRzKFQuU2V1cmF0KSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKI0RHRSBiZXR3ZWVuIDAgYW5kIDEyCmRnZWNkNF9kYXRhIDwtIHJlYWQudGFibGUocGFzdGUoV09SS0lOR19ESVIsICIvMDJfU2V1cmF0X2FuYWx5c2lzLzAxX1NjcmlwdC9kZ2VDRDRkYXRhLnR4dCIsc2VwPSIiKSwgc2VwID0gIlx0IikKIyBiYXIgcGxvdAojYWRkIGFicyB2YWx1ZSB0byB0YWJsZQpkZ2VjZDRfZGF0YSRhYnMgPC0gYWJzKGRnZWNkNF9kYXRhJGF2Z19sb2dGQykgCgpkZ2VjZDRfZGF0YSRnZW5lbmFtZSA8LSByb3duYW1lcyhkZ2VjZDRfZGF0YSkKIyBTZWxlY3QgbWFya2VycyBmb3IgcGxvdHRpbmcgb24gYSBIZWF0bWFwIAptYXJrZXJzLnVzZT1zdWJzZXQoZGdlY2Q0X2RhdGEscF92YWxfYWRqPDFlLTEwICYgYWJzPjAuMikKZGZjZDRtYXJrZXJzIDwtbWFya2Vycy51c2Vbb3JkZXIobWFya2Vycy51c2UkYXZnX2xvZ0ZDKSxdCgpkZmNkNG1hcmtlcnMkZ2VuZW5hbWUgPC0gZmFjdG9yKGRmY2Q0bWFya2VycyRnZW5lbmFtZSwgbGV2ZWxzID0gZGZjZDRtYXJrZXJzJGdlbmVuYW1lW29yZGVyKGRmY2Q0bWFya2VycyRhdmdfbG9nRkMpXSkKZGZjZDRtYXJrZXJzJGxvZ3B2YWwgPC0gbG9nMTAoZGZjZDRtYXJrZXJzJHBfdmFsX2FkaikKCmBgYAoKCmBgYHtyLGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gOH0KZ2dwbG90KGRmY2Q0bWFya2VycywgYWVzKHggPSBkZmNkNG1hcmtlcnMkZ2VuZW5hbWUsIHkgPSBkZmNkNG1hcmtlcnMkYXZnX2xvZ0ZDLCBmaWxsID0gbG9ncHZhbCkpICsgICAjIEZpbGwgY29sdW1uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IC42KSArICAgIyBkcmF3IHRoZSBiYXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsaW0oLTEuMiwxLjIpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJzKHRpdGxlPSJER0UgLSBDbHVzdGVyIDAgdnMgMTIgKENkNCBuYWl2ZSkiLHkgPSJMb2cgZm9sZCBjaGFuZ2UiLCB4ID0gIkdlbmVzIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWVfdHVmdGUoKSArICAjIFR1ZnRlIHRoZW1lIGZyb20gZ2dmb3J0aWZ5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0PTEpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93PSdyZWQnLCBtaWQ9J29yYW5nZScsIGhpZ2g9J2JsdWUnLG1pZHBvaW50ID0gLTQwLCBicmVha3M9YygtMTIsLTQwLC01NyksbGFiZWxzPWMoIi0xMCIsIi00MCIsIi02MCIpKSsgY29vcmRfZmxpcCgpICMgRmxpcCBheGVzCmBgYAoKCiMjIyMgUGFuZWwgQwoKYGBge3J9CklkZW50cyhULlNldXJhdCkgPC0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiCgojIGdldCBhbGwgZ2VuZSBuYW1lIGV4cHJlc3MgaW4gb3VyIGNlbGxzIGFzIGJhY2tncm91bmQKYmFja2dyb3VuZCA8LSBULlNldXJhdEBhc3NheXMkUk5BQG1ldGEuZmVhdHVyZXMKYmFja2dyb3VuZHJvdyA8LSByb3duYW1lcyhiYWNrZ3JvdW5kKQpgYGAKCmBgYHtyLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0KZ2VuZWNvbXByb3cgPC0gcmVhZC50YWJsZShwYXN0ZShXT1JLSU5HX0RJUiwgIi8wMl9TZXVyYXRfYW5hbHlzaXMvMDFfU2NyaXB0L2NsdXN0ZXIxdjQudHh0IixzZXA9IiIpLCBzZXAgPSAiXHQiKQpnZW5lY29tcHJvdyR4ID0gYXMuY2hhcmFjdGVyKGdlbmVjb21wcm93JHgpCmdlbmVjb21wcm93IDwtIGdlbmVjb21wcm93WywxXQoKQ1BlbnJpY2ggPC0gZW5yaWNoR08oZ2VuZT0gZ2VuZWNvbXByb3csIE9yZ0RiID0gJ29yZy5NbS5lZy5kYicsIG9udD0iQlAiLGtleVR5cGUgPSAiU1lNQk9MIix1bml2ZXJzZSA9IGJhY2tncm91bmRyb3cpICMgb3JnLk1tLmVnLmRiIGdlbm9tZSBtb3VzZQojaGVhZCAoQ1BlbnJpY2gpCgpgYGAKCmBgYHtyLGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gNn0KZG90cGxvdChDUGVucmljaCwgc2hvd0NhdGVnb3J5PTE1LGNvbG9yID0gInAuYWRqdXN0Iix4PSJjb3VudCIpICMrIGNvb3JkX2ZsaXAoKSt0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQpgYGAKCiMjIyMgUGFuZWwgRAoKYGBge3J9CmdlbmVjb21wcm93IDwtIHJlYWQudGFibGUocGFzdGUoV09SS0lOR19ESVIsICIvMDJfU2V1cmF0X2FuYWx5c2lzLzAxX1NjcmlwdC9jbHVzdGVyMHZzMTIudHh0IixzZXA9IiIpLCBzZXAgPSAiXHQiKQpnZW5lY29tcHJvdyR4ID0gYXMuY2hhcmFjdGVyKGdlbmVjb21wcm93JHgpCmdlbmVjb21wcm93IDwtIGdlbmVjb21wcm93WywxXQojIyMjCgoKQ1BlbnJpY2ggPC0gZW5yaWNoR08oZ2VuZT0gZ2VuZWNvbXByb3csIE9yZ0RiID0gJ29yZy5NbS5lZy5kYicsIG9udD0iQlAiLGtleVR5cGUgPSAiU1lNQk9MIix1bml2ZXJzZSA9IGJhY2tncm91bmRyb3cpICMgb3JnLk1tLmVnLmRiIGdlbm9tZSBtb3VzZQpgYGAKCmBgYHtyLGZpZy53aWR0aCA9IDksIGZpZy5oZWlnaHQgPSA2IH0KZG90cGxvdChDUGVucmljaCwgc2hvd0NhdGVnb3J5PTE1LGNvbG9yID0gInAuYWRqdXN0Iix4PSJjb3VudCIpKyBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscz1mdW5jdGlvbih4KXN0cl93cmFwKHgsIHdpZHRoPTQwKSkKYGBgCgojIyMgU3VwcGxlbWVudGFyeSA0CiMjIyMgUGFuZWwgQQpgYGB7cn0KI0RPVCBwbG90IGV5RlAgYW5kIFRHRCBvbiBDRDggZWZmZWN0b3IgYW5kIG1lbW9yeQpJZGVudHMoVC5TZXVyYXQuc3BsZWVuKSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKQ0Q4c3ViIDwtIHN1YnNldChULlNldXJhdC5zcGxlZW4sIGlkZW50cyA9IGMoIjExIiwiMTkiLCIxMyIpKQpJZGVudHMoQ0Q4c3ViKSA8LSAiTVVMVElfSUQiCkNEOHN1YkBhY3RpdmUuaWRlbnQgPC0gZmFjdG9yKENEOHN1YkBhY3RpdmUuaWRlbnQsbGV2ZWxzPWMoIlNwbGVlbi1NIiwiU3BsZWVuLU1QIiwiU3BsZWVuLWN0cmwiLCJTcGxlZW4tUCIpKQojbGV2ZWxzKENEOHN1YikKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQpEb3RQbG90KENEOHN1YiwgZG90LnNjYWxlID0gOCxmZWF0dXJlcyA9IGMoIlRjcmctQzEiLCJUcmRjIiwiVHJiYzIiLCJUcmFjIiwiZVlGUCIpICkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdyA9ICJzdGVlbGJsdWUiLCBtaWQgPSAid2hpdGUiLCBoaWdoID0gInJlZCIpKyBnZ3RpdGxlKCJDRDggbWVtb3J5IGFuZCBlZmZlY3RvciBjbHVzdGVycyIpCmBgYAo=